package web

import (
	"io/ioutil"
	"path"
	"reflect"

	"github.com/gin-gonic/gin"
	"github.com/prometheus/common/log"
)

type TemplateProduct struct {
	TemplatesDir string
	gt           map[string]*Jade
	CB           map[string](func(*gin.Context) gin.H)
}

func (ep *TemplateProduct) NewElement(fn string) *Jade {
	j, err := NewJade(path.Join(ep.TemplatesDir, fn))
	if err != nil {
		log.Error(err)
		return nil
	}
	ep.gt[fn] = j
	return j
}

func (ep *TemplateProduct) Render(c *gin.Context, name string, Data gin.H) {
	ep.gt[name].SetObj(Data)
	ep.gt[name].Execute(c)
}

var (
	GlobTemplates TemplateProduct
)

func LoadTemplate(dir string) {
	GlobTemplates = TemplateProduct{
		dir,
		make(map[string]*Jade),
		make(map[string](func(*gin.Context) gin.H)),
	}
	files, _ := ioutil.ReadDir(dir)
	for _, fi := range files {
		if !fi.IsDir() && path.Ext(fi.Name()) == ".jade" {
			GlobTemplates.NewElement(fi.Name())
		}
	}
	GlobTemplates.Init()
}

func (gt *TemplateProduct) BuildRender(r string) func(c *gin.Context) {
	return func(c *gin.Context) {
		var obj gin.H
		if cb, ok := gt.CB[r]; ok {
			obj = cb(c)
		}
		gt.Render(c, r, obj)
	}
}

func (gt *TemplateProduct) SetCB(r string, cb func(c *gin.Context) gin.H) {
	gt.CB[r] = cb
}

func (gt *TemplateProduct) Init() {
	gt.SetCB("rx_port.jade", func(c *gin.Context) gin.H {
		port := Str2int(c.DefaultQuery("port", "0"))
		r, _ := GlobPorts.GetPort(port)
		gr := make(gin.H)
		Obj2GinH(*&r.RFConfig, gr)
		Obj2GinH(*r, gr)
		gr["Gain"] = float32(gr["Gain"].(reflect.Value).Int()) / 10.
		return gr
	})
}

func Obj2GinH(obj interface{}, r gin.H) {
	// log.Info(reflect.ValueOf(obj).Kind())
	if reflect.ValueOf(obj).Kind() == reflect.Struct {
		v := reflect.ValueOf(obj)
		k := v.Type()
		// log.Info("Number of fields", v.NumField())
		for i := 0; i < v.NumField(); i++ {
			sv := v.Field(i)
			sk := k.Field(i)
			// log.Infof("Field:%d type:%T value:%v\n", i, sv, sv)
			r[sk.Name] = sv
		}
	}
	return
}
